package cn.ultrarisk.scadmin.manager.biz.solr.dto;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.Node;
import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * CollectionSchema
 *
 * @author sevendlong(lin23871@163.com)
 * @date 2014/6/6
 * @since V1.0
 */
public class CollectionSchema implements Serializable {
    private static final long serialVersionUID = -766849130079677553L;

    private String name;
    private String version;
    private List<CollectionSchemaType> types;
    private List<CollectionSchemaField> fields;
    private String uniqueKey;
    private String defaultSearchField;
    private String defaultOperator;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public List<CollectionSchemaType> getTypes() {
        return types;
    }

    public void setTypes(List<CollectionSchemaType> types) {
        this.types = types;
    }

    public void addType(CollectionSchemaType type) {
        if (this.types == null) {
            this.types = new ArrayList<CollectionSchemaType>();
        }
        this.types.add(type);
    }

    public List<CollectionSchemaField> getFields() {
        return fields;
    }

    public void setFields(List<CollectionSchemaField> fields) {
        this.fields = fields;
    }

    public void addField(CollectionSchemaField field) {
        if (this.fields == null) {
            this.fields = new ArrayList<CollectionSchemaField>();
        }
        this.fields.add(field);
    }

    public String getUniqueKey() {
        return uniqueKey;
    }

    public void setUniqueKey(String uniqueKey) {
        this.uniqueKey = uniqueKey;
    }

    public String getDefaultSearchField() {
        return defaultSearchField;
    }

    public void setDefaultSearchField(String defaultSearchField) {
        this.defaultSearchField = defaultSearchField;
    }

    public String getDefaultOperator() {
        return defaultOperator;
    }

    public void setDefaultOperator(String defaultOperator) {
        this.defaultOperator = defaultOperator;
    }

    public CollectionSchemaField getFieldByName(String name) {
        for (CollectionSchemaField field : fields) {
            if (name.equals(field.getName())) {
                return field;
            }
        }
        return null;
    }

    public static CollectionSchema fromXml(String schemaXml) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setIgnoringElementContentWhitespace(true);

        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new ByteArrayInputStream(schemaXml.getBytes("UTF-8")));
            Element root = doc.getDocumentElement();

            CollectionSchema schema = new CollectionSchema();
            schema.setName(root.getAttribute("name"));
            schema.setVersion(root.getAttribute("version"));

            NodeList typeNodes = root.getElementsByTagName("types").item(0).getChildNodes();
            for (int i = 0; i < typeNodes.getLength(); i++) {
                if (typeNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
                    Element typeNode = (Element) typeNodes.item(i);
                    String name = typeNode.getAttribute("name");
                    String clazz = typeNode.getAttribute("class");
                    schema.addType(new CollectionSchemaType(name, clazz));
                }
            }
            NodeList fieldNodes = root.getElementsByTagName("fields").item(0).getChildNodes();
            for (int i = 0; i < fieldNodes.getLength(); i++) {
                if (fieldNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
                    Element fieldNode = (Element) fieldNodes.item(i);
                    String name = fieldNode.getAttribute("name");
                    if ("_version_".equals(name)) {
                        continue;
                    }
                    String type = fieldNode.getAttribute("type");
                    String indexed = fieldNode.getAttribute("indexed");
                    String stored = fieldNode.getAttribute("stored");
                    String multiValued = fieldNode.getAttribute("multiValued");
                    String required = fieldNode.getAttribute("required");
                    Boolean dynamicField = fieldNode.getTagName().equals("dynamicField");
                    schema.addField(new CollectionSchemaField(name, type, indexed, stored, multiValued, required, dynamicField));
                }
            }
            schema.setUniqueKey(((Element) root.getElementsByTagName("uniqueKey").item(0)).getTextContent().trim());
            schema.setDefaultSearchField(((Element) root.getElementsByTagName("defaultSearchField").item(0)).getTextContent().trim());
            schema.setDefaultOperator(((Element) root.getElementsByTagName("solrQueryParser").item(0)).getAttribute("defaultOperator"));

            NodeList copyFieldNodes =  root.getElementsByTagName("copyField");
            for (int i = 0; i < copyFieldNodes.getLength(); i++) {
                Element copyFieldNode = (Element) copyFieldNodes.item(i);
                String destFieldName = copyFieldNode.getAttribute("dest");
                CollectionSchemaField copyField = schema.getFieldByName(destFieldName);
                if (copyField != null) {
                    copyField.setCopyField(true);
                }
            }
            return schema;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
